module ameter
import StdEnv, japi

/* *********************************
This examples shows a voltmeter interface.
If you ever build such an instrument, you may
consider writing a Clean interface for it.
***************************************/

:: State= { frame::!Framer, start::!TDev,
             buttonpanel::!Container, phase::!Int,
             tens::!D, secs::!D, chrono::Bool,
             vmeter::!TDev, padpanel::!Container}

Start world
  # (js, world) = begin_japi world
    (frm, js) = jnewFrame FLOW  "Voltmeter" js
    (frm, js) = jverticalLayout frm js
    (frm, js) = vGap frm 60 js
    (pad, js)= jnewPanel FLOW frm js
    (meter, js)=jnewMeter(WH 300 200) "Volt" pad js
    (meter, js)= jsetmin meter -300 js
    (meter, js)= jsetmax meter 300 js
    (meter, js)= jsetdanger meter 220 js
    
    (panel, js)= jnewPanel FLOW frm js
    (panel, js)= jhorizontalLayout panel js
    (panel, js)= hGap panel 20 js
    (t, js) = jnew7seg (WH 40 50) 0 J_RED panel  js
    (u, js) = jnew7seg  (WH 40 50) 0 J_RED panel js
    
    (mp, js) = jnewButton FLOW "start" frm js
    (frm, js)= jpack frm js
    (frm, js) = jshow frm js
    s= { frame=frm, start=mp, vmeter= meter,
         tens= t, secs= u, phase= 0, chrono= False,
         padpanel=pad, buttonpanel= panel}
    js= loop s js
  = end_japi js world
where
    pi= 4.0 * (atan 1.0)
    sinus p= sin ((2.0 * pi) * ((toReal p)/60.0)) 
    
    loop :: !State !JapiState -> JapiState
    loop s js
       # (x, js) = jsleep 200 js
       # (na, js) = jgetaction x js
       | na== (act s.frame) = jquit js
       | na== (act s.start) && s.chrono
           # (t, js)= jsetval s.tens 0 js
             (u, js) = jsetval s.secs 0 js
             (v, js) = jsetval s.vmeter 0 js
             b= jsetText s.start "Start"
           = loop { s&chrono= False, phase= 0, start= b, 
                    tens= t, secs=u, vmeter= v} js
       | na== (act s.start) && (not s.chrono)
           = loop {s&chrono= True} js
       | s.chrono
           # p= (s.phase+1) rem 60
           # (t, js)= jsetval s.tens (p/10) js
             (u, js) = jsetval s.secs (p rem 10) js
             v= toInt(220.0 * (sinus p))
             (m, js)= jsetval s.vmeter v js
             b= jsetText s.start "Stop"
           = loop {  s& secs= u, start= b, 
                     tens=t, phase= p, vmeter=m} js
       | otherwise = loop s js
   
 